1 2 3 /* 4 Boiler plate for irp cancelation, for irp queues you manage yourself 5 -Gunnar 6 */ 7 8 9 10 CancelRoutine( 11 DEV_OBJ Dev, 12 Irp 13 ) 14 { 15 //don't need this since we have our own sync. protecting irp cancellation 16 IoReleaseCancelSpinLock(Irp->CancelIrql); 17 18 theLock = Irp->Tail.Overlay.DriverContext[3]; 19 20 Lock(theLock); 21 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 22 Unlock(theLock); 23 24 Irp->IoStatus.Status = STATUS_CANCELLED; 25 Irp->IoStatus.Information = 0; 26 27 IoCompleteRequest(Irp, IO_NO_INCREMENT); 28 29 } 30 31 32 QUEUE_BOLIERPLATE 33 { 34 Lock(theLock); 35 36 Irp->Tail.Overlay.DriverContext[3] = &theLock; 37 38 IoSetCancelRoutine(Irp, CancelRoutine); 39 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL)) 40 { 41 /* 42 Irp has already been cancelled (before we got to queue it), 43 and we got to remove the cancel routine before the canceler could, 44 so we cancel/complete the irp ourself. 45 */ 46 47 Unlock(theLock); 48 49 Irp->IoStatus.Status = STATUS_CANCELLED; 50 Irp->IoStatus.Information = 0; 51 IoCompleteRequest(Irp, IO_NO_INCREMENT); 52 53 return FALSE; 54 } 55 56 //else were ok 57 58 59 Irp->IoStatus.Status = STATUS_PENDING; 60 IoMarkIrpPending(Irp); 61 62 InsertTailList(Queue); 63 64 Unlock(theLock); 65 66 } 67 68 69 DEQUEUE_BOILERPLATE 70 { 71 Lock(theLock); 72 73 Irp = RemoveHeadList(Queue); 74 75 if (!IoSetCancelRoutine(Irp, NULL)) 76 { 77 /* 78 Cancel routine WILL be called after we release the spinlock. It will try to remove 79 the irp from the list and cancel/complete this irp. Since we allready removed it, 80 make its ListEntry point to itself. 81 */ 82 83 InitializeListHead(&Irp->Tail.Overlay.ListEntry); 84 85 Unlock(theLock); 86 87 return; 88 } 89 90 91 /* 92 Cancel routine will NOT be called, canceled or not. 93 The Irp might have been canceled (Irp->Cancel flag set) but we don't care, 94 since we are to complete this Irp now anyways. 95 */ 96 97 Unlock(theLock); 98 99 Irp->IoStatus.Status = STATUS_SUCCESS; 100 Irp->IoStatus.Information = 0; 101 IoCompleteRequest(Irp, IO_NO_INCREMENT); 102 103 } 104